/**
 * @Author       : Hejh(3010733382@qq.com)
 * @Version      : V1.0
 * @Date         : 2024-01-14 17:38:59
 * @Description  : 考试记录接口的验证中间件
 */
const Joi = require('joi')
const { Op } = require('sequelize')
const R = require('@/models/Response')
const { ExamHistory, User } = require('@/models/model')
const { ERROR_USER_CODE, ERROR_SYSTEM_CODE } = require('@/constants/errorCode')
const { IS_INTEGER, IS_UNSAFE_INTEGER } = require('@/constants/joiSchema')
const { dumpCheck: globalDumpCheck } = require('@/utils/dumpCheck')

const examHistorySchema = {
  examHistoryIds: Joi.array().items(IS_UNSAFE_INTEGER),
  examHistoryId: IS_UNSAFE_INTEGER,
  paperId: IS_UNSAFE_INTEGER,
  userId: IS_UNSAFE_INTEGER,
  page: IS_INTEGER.min(1).default(1),
  pageSize: IS_INTEGER.min(1).default(999),
  answers: Joi.string(),
  type: Joi.number().valid(1, 2, 3)
}

const dumpCheck = {
  /**
   * @author: Hejh(3010733382@qq.com)
   * @description: 验证考试记录ID的合法性
   * @param {array<string>} examHistoryIds 考试记录ID数组
   */
  checkExamHistoryIds: async (examHistoryIds) => {
    let newexamHistoryIds = [...new Set(examHistoryIds)]
    // 不能出现重复的
    if (newexamHistoryIds.length !== examHistoryIds.length) {
      return false
    }

    newexamHistoryIds = newexamHistoryIds.map((item) => BigInt(item))

    if (newexamHistoryIds.length === 0) {
      return true
    }

    // 查看不重复的和数据库的是否对的上
    const myWhere = {
      id: {
        [Op.in]: newexamHistoryIds
      }
    }
    const examHistorys = await ExamHistory.findAll({
      where: myWhere
    })
    if (examHistorys.length !== newexamHistoryIds.length) {
      return false
    }

    return true
  }
}

/**
 * @description 考试记录列表查询的参数验证
 * @param {*} ctx
 * @param {*} next
 * @returns
 */
module.exports.listExamHistoryValidate = async (ctx, next) => {
  const schema = Joi.object({
    page: examHistorySchema.page,
    pageSize: examHistorySchema.pageSize,
    paperId: examHistorySchema.paperId,
    userId: examHistorySchema.userId,
    type: examHistorySchema.type
  }).validate(ctx.query)

  if (schema.error) {
    ctx.body = R.error(ERROR_SYSTEM_CODE.PARAMS_SCHEMA_ERROR)
    return
  }
  ctx.query = schema.value
  await next()
}

/**
 * @description 创建考试记录时的参数验证
 * @param {*} ctx
 * @param {*} next
 * @returns
 */
module.exports.createExamHistoryValidate = async (ctx, next) => {
  const schema = Joi.object({
    paperId: examHistorySchema.paperId.required(),
    userId: examHistorySchema.userId.required(),
    answers: examHistorySchema.answers.required(),
    type: examHistorySchema.type
  }).validate(ctx.request.body)

  if (schema.error) {
    ctx.body = R.error(ERROR_SYSTEM_CODE.PARAMS_SCHEMA_ERROR)
    return
  }

  const { paperId, userId } = ctx.request.body

  // 验证试卷ID的合法性，用户ID的合法性
  const b1 = await globalDumpCheck.checkUserIds([userId])
  if (!b1) {
    ctx.body = R.error(ERROR_USER_CODE.USER_ID_ERROR)
    return
  }

  const b2 = await globalDumpCheck.checkPaperIds([paperId])
  if (!b2) {
    ctx.body = R.error(ERROR_USER_CODE.PAPER_ID_ERROR)
    return
  }
  // 到这里说明参数没有问题,协作考试记录情况[0],[-1],[xxx,xxx]
  await next()
}

/**
 * @author: Hejh(3010733382@qq.com)
 * @description: 批量删除考试记录接口的参数验证
 * @param {*} ctx
 * @param {*} next
 */
module.exports.delExamHistorysValidate = async (ctx, next) => {
  const schema = Joi.object({
    examHistoryIds: examHistorySchema.examHistoryIds.required()
  }).validate(ctx.request.body)

  if (schema.error) {
    ctx.body = R.error(ERROR_SYSTEM_CODE.PARAMS_SCHEMA_ERROR)
    return
  }

  const { examHistoryIds } = ctx.request.body

  // 验证考试记录ID数组的合法性
  const b4 = await dumpCheck.checkExamHistoryIds(examHistoryIds)
  if (!b4) {
    ctx.body = R.error(ERROR_USER_CODE_EXAM_HISTORY_ID_ERROR)
    return
  }

  await next()
}

/**
 * @author: Hejh(3010733382@qq.com)
 * @description: 考试记录排序接口的参数验证
 * @param {*} ctx
 * @param {*} next
 */
module.exports.sortExamHistorysValidate = async (ctx, next) => {
  const schema = Joi.object({
    examHistoryIds: examHistorySchema.examHistoryIds.required()
  }).validate(ctx.request.body)

  if (schema.error) {
    ctx.body = R.error(ERROR_SYSTEM_CODE.PARAMS_SCHEMA_ERROR)
    return
  }

  const { examHistoryIds } = ctx.request.body

  // 验证考试记录ID数组的合法性
  const b4 = await dumpCheck.checkExamHistoryIds(examHistoryIds)
  if (!b4) {
    ctx.body = R.error(ERROR_USER_CODE.EXAM_HISTORY_ID_ERROR)
    return
  }

  await next()
}
